#include "Config.h"

void setup(){
  Serial.begin(115200);
  matrix.begin();
  matrix.setTextWrap(false);
  matrix.setBrightness(brightnessNow);
  WiFiManager wifiManager;
  showFirmwareInfo(3, 1, true);
  wifiManager.autoConnect(WIFI_NAME);
  showFirmwareInfoEnd();
  showWiFiDoneAnimation(true);
  Serial.println("WIFI online!");
  configTime(8 * 3600, 0,"ntp1.aliyun.com","ntp2.aliyun.com","ntp3.aliyun.com");
  timeClient.update();
  EEPROM.begin(EEPROM_SIZE);
  // 如果值为123则判断存有预置值
  if (EEPROM.read(EEPROM_GAIN) != 123) {
    EEPROM.write(EEPROM_GAIN, 123);
    EEPROM.write(EEPROM_BRIGHTNESS, BRIGHTNESS);
    EEPROM.write(EEPROM_MODE, Mode);
    EEPROM.write(EEPROM_COLOR, hue/2);
    EEPROM.write(EEPROM_COLOR_H, hueh/2);
    EEPROM.write(EEPROM_COLOR_M, huem/2);
    EEPROM.write(EEPROM_COLOR_S, hues/2);
    EEPROM.write(EEPROM_COLOR_W, huew/2);
    EEPROM.write(EEPROM_PIC_X, pic_x);
    EEPROM.write(EEPROM_PIC_Y, pic_y);
    EEPROM.write(EEPROM_CLOCK_MODE, clockMode);
    EEPROM.write(EEPROM_DATE_MODE, dateMode);
    EEPROM.write(EEPROM_LOOP_MODE, loopMode);
    EEPROM.write(EEPROM_B_FANS_MODE, bFansMode);
    EEPROM.write(EEPROM_COLOR_B, hueb/2);
    EEPROM.commit();
  }else{
    brightnessNow = EEPROM.read(EEPROM_BRIGHTNESS);
    Mode = EEPROM.read(EEPROM_MODE);
    hue = int(EEPROM.read(EEPROM_COLOR))*2;
    hueh = int(EEPROM.read(EEPROM_COLOR_H))*2;
    huem = int(EEPROM.read(EEPROM_COLOR_M))*2;
    hues = int(EEPROM.read(EEPROM_COLOR_S))*2;
    huew = int(EEPROM.read(EEPROM_COLOR_W))*2;
    pic_x = int(EEPROM.read(EEPROM_PIC_X));
    pic_y = int(EEPROM.read(EEPROM_PIC_Y));
    clockMode = int(EEPROM.read(EEPROM_CLOCK_MODE));
    dateMode = int(EEPROM.read(EEPROM_DATE_MODE));
    loopMode = int(EEPROM.read(EEPROM_LOOP_MODE));
    bFansMode = int(EEPROM.read(EEPROM_B_FANS_MODE));
    hueb = int(EEPROM.read(EEPROM_COLOR_B))*2;
  }
  matrix.setBrightness(brightnessNow);
  ShowIP();
  InitServer();
  button.attachClick(changeToFlashBackMode);
  button.attachDoubleClick(nextMode);
  switchMode(true,Mode);
}

//切换至时光回溯模式
void changeToFlashBackMode(){
  Serial.println("按钮切换时光回溯");
  toTargetMode(FLASH_BACK_MODE);
}

//切换至指定模式
void toTargetMode(int m){
  if(m<MODE_MAX+1 && m>0){
    int oldMode = Mode;
    Mode = m;
    Serial.print("web切换模式：");
    Serial.println(m);
    modeChange(oldMode, Mode);//模式切换
  }
}

//下一个模式
void nextMode(){
  int oldMode = Mode;
  if (++Mode > MODE_MAX)Mode = 1;//模式变化
  int newMode = Mode;
  modeChange(oldMode, newMode);//模式切换
}

//模式变更
void modeChange(int oldMode, int newMode)
{
  loopChangeStatus = true;
  switchLoopMode(oldMode,newMode);
  Serial.println("切换模式");
  Serial.println(Mode);
  loopChangeStatus = false;
  Serial.println("切换模式: 恢复loopChangeStatus");
  switchMode(true,Mode);
}

//模式循环变更
void modeLoopChange(int mode1, int mode2){
  int oldMode = LOOP_MODE_NOW;
  int newMode = 1;
  if(oldMode == mode1){
    newMode = mode2;
  }else if(oldMode == mode2){
    newMode = mode1;
  }else{
    oldMode = mode1;
    newMode = mode2;
  }
  switchLoopMode(oldMode,newMode);
  LOOP_MODE_NOW = newMode;
}

//设置保存
void configSave(){
  Serial.println("按键保存配置");
  if (EEPROM.read(EEPROM_GAIN) != 123) {  // not equal to 123
    EEPROM.write(EEPROM_GAIN, 123);  // write value 123 to byte 256
  }
  EEPROM.write(EEPROM_BRIGHTNESS, brightnessNow);
  EEPROM.write(EEPROM_MODE, Mode);
  EEPROM.write(EEPROM_COLOR, hue/2);
  EEPROM.write(EEPROM_COLOR_H, hueh/2);
  EEPROM.write(EEPROM_COLOR_M, huem/2);
  EEPROM.write(EEPROM_COLOR_S, hues/2);
  EEPROM.write(EEPROM_COLOR_W, huew/2);
  EEPROM.write(EEPROM_PIC_X, pic_x);
  EEPROM.write(EEPROM_PIC_Y, pic_y);
  EEPROM.write(EEPROM_CLOCK_MODE, clockMode);
  EEPROM.write(EEPROM_DATE_MODE, dateMode);
  EEPROM.write(EEPROM_LOOP_MODE, loopMode);
  EEPROM.write(EEPROM_B_FANS_MODE, bFansMode);
  EEPROM.write(EEPROM_COLOR_B, hueb/2);
  EEPROM.commit();
  int x = xres;
  for(int i=0;i<52;i++){
    matrix.clear();
    matrix.fillScreen(0);
    matrix.setCursor(x, 0);
    matrix.print(F("Saved"));
    matrix.setTextColor(matrix.Color(148,0,211));
    if(--x < -36) {
      x = matrix.width();
    }
    matrix.show();
    system_soft_wdt_feed();
    delay(70);
  }
  matrix.clear();
  switchMode(true,Mode);
}


//显示日期
void showMouthDay(bool implement) {
  if ( millis() - lastTime > 2000 | implement)
  {
    timeClient.update();
    //将epochTime换算成年月日
    unsigned long epochTime = timeClient.getEpochTime();
    struct tm *ptm = gmtime((time_t *)&epochTime);
    monthDay = ptm->tm_mday;
    currentMonth = ptm->tm_mon + 1;
    Serial.println(monthDay);
    Serial.println(currentMonth);
    lastTime = millis();
    matrix.clear();
  }
  //String monthDayStr = monthDay>9? String(monthDay):('0'+String(monthDay));
  //String currentMonthStr = currentMonth>9? String(currentMonth):('0'+String(currentMonth));
  switch(dateMode){
    case 1:
      showbitnumber(currentMonth,3,5,6+GlobalX,1+GlobalY,hsv2rgb(hueh, saturation, value));
      showbitnumber(monthDay,3,5,18+GlobalX,1+GlobalY,hsv2rgb(huem, saturation, value));
      matrix.drawPixel(15+GlobalX,3+GlobalY,hsv2rgb(hue, saturation, value));
      drawFastYLine(14+GlobalX,4+GlobalY,2,hsv2rgb(hue, saturation, value));
      drawFastYLine(16+GlobalX,1+GlobalY,2,hsv2rgb(hue, saturation, value));
      //星期
      showWeek(2+GlobalX,7+GlobalY,huew,3);
      break;
    case 2:
      SetEmoji(pic_x, pic_y);
      showbitnumber(currentMonth,3,5,12+GlobalX,1+GlobalY,hsv2rgb(hueh, saturation, value));
      matrix.drawPixel(20+GlobalX,3+GlobalY,hsv2rgb(hue, saturation, value));
      matrix.drawPixel(21+GlobalX,3+GlobalY,hsv2rgb(hue, saturation, value));
      showbitnumber(monthDay,3,5,23+GlobalX,1+GlobalY,hsv2rgb(huem, saturation, value));
      //星期
      showWeek(11+GlobalX,7+GlobalY,huew,2);
      break;
  }
}

//显示时间
void showTime(bool implement)
{
  if ( millis() - lastTime > 200 | implement)
  {
    timeClient.update();
    H = timeClient.getFormattedTime().substring(0, 2).toInt();
    M = timeClient.getFormattedTime().substring(3, 5).toInt();
    S = timeClient.getFormattedTime().substring(6, 8).toInt();
    D = timeClient.getDay();
    
    lastTime = millis();
  }
  switch(clockMode){
      case 1:
        ClockMode1();
        break;
      case 2:
        ClockMode2();
        break;
      case 3:
        ClockMode3();
        break;
      case 4:
        ClockMode4();
        break;
      default:
        ClockMode1();
  }
}

//日期+时间轮播方法
void showDateLoop()
{
  if(millis() - loopTime > 5000 ){
    lastTime = millis()-1000;
    modeLoopChange(TIME_MODE,DAY_MODE);
    loopTime = millis();
  }else{
    switchMode(false,LOOP_MODE_NOW);
    delay(16);
  }
}

void movingPixel(int x, int y, int colorh){
    int pixel = y;
    matrix.drawPixel(x, pixel, hsv2rgb(colorh, 100, 100 ));
    if(pixel-1 >= 0){ matrix.drawPixel(x, pixel-1, hsv2rgb(colorh, 80, 80 ));}
    if(pixel-2 >= 0){ matrix.drawPixel(x, pixel-2, hsv2rgb(colorh, 70, 70 ));}
    if(pixel-3 >= 0){ matrix.drawPixel(x, pixel-3, hsv2rgb(colorh, 45, 45 ));}
    if(pixel-4 >= 0){ matrix.drawPixel(x, pixel-4, hsv2rgb(colorh, 25, 25 ));}
    if(pixel-5 >= 0){ matrix.drawPixel(x, pixel-5, hsv2rgb(colorh, 10, 10 ));}
    if(pixel-6 >= 0){ matrix.drawPixel(x, pixel-6, matrix.Color(0, 0, 0));}
}

//代码雨
void showRainingCode(bool implement) {
  if ( millis() - lastTime > 100 | implement)
  {
    if(!implement){
      lastTime = millis();
    }
    for(int i=0; i<8; i++){
      if(stepIndex[i] > stepsTillNext[i]){
        Running[i] = true;
        stepsTillNext[i] = 13;  // 进行数组初始化
        columnIndex[i] = random((i*4), ((i+1)*4));
        stepIndex[i] = 0;
      }
      if(Running[i] == true){
        movingPixel(columnIndex[i]+GlobalX, stepIndex[i]+GlobalY, colorh);
        if(stepIndex[i] == 13){
          Running[i] = false;
        }
      }
      stepIndex[i] += 1;
    }
    //matrix.show();
  }
}

//B站粉丝数
void showBlibliFans(bool implement){
  int ani = 0;
  long dis = millis() - lastTime;
  if ( dis > 20000 | implement)
  {
    ParseFans(FansURL);    //更新粉丝数
    Serial.println(Fansnumber);    //打印粉丝数
    lastTime = millis();
  }
  if(50< dis && dis < 100){
    ani = 1;
  }else if(dis < 200){
    ani = 2;
  }else if(dis < 270){
    ani = 1;
  }
  matrix.clear();
  BPattern(ani);
  showBFansNumber();
  matrix.show();
}

//切换模式
void switchMode(bool change, int mode){
  switch (mode)
  {
    case TIME_MODE:
      showTime(change);
      break;
    case DAY_MODE:
      showMouthDay(change);
      break;
    case DATE_LOOP_MODE:
      if(change){
        loopTime = millis();
      }
      showDateLoop();
      break;
    case WEATHER_MODE:
      showWeatherDay(change);
      break;
    case RAINING_MODE:
      showRainingCode(change);
      break;
    case BFANS_MODE:
      showBlibliFans(change);
      break;
    case FLASH_BACK_MODE:
      showFlashBack(change);
      break;
  }
}

void loop()
{
  button.tick();
  WebServer_run();
  switchMode(false,Mode);
  delay(10);
  matrix.show();
}
